package com.tan.core.utils;


import org.redisson.api.*;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Tan
 * @description redisson 工具
 * @date 2025/2/7
 */
@Component
public class RedissonTool {

    private final RedissonClient redissonClient;

    @Autowired
    public RedissonTool(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }


    /**
     * 获取分布式锁
     *
     * @param lockName  锁的名称
     * @param waitTime  等待获取锁的最大时间
     * @param leaseTime 锁的自动释放时间
     * @param timeUnit  时间单位
     * @return 是否成功获取锁
     */
    public boolean tryLock(String lockName, long waitTime, long leaseTime, TimeUnit timeUnit) {
        RLock lock = redissonClient.getLock(lockName);
        try {
            return lock.tryLock(waitTime, leaseTime, timeUnit);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    /**
     * 释放分布式锁
     *
     * @param lockName 锁的名称
     */
    public void unlock(String lockName) {
        RLock lock = redissonClient.getLock(lockName);
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }

    /**
     * 设置对象到缓存
     * 一周过期
     *
     * @param key   键
     * @param value 值
     * @param <T>   对象类型
     */
    public <T> void cacheObjWeek(String key, T value) {
        if (value == null || StringUtils.isBlank(String.valueOf(value))) {
            return;
        }
        if (value instanceof ArrayList && ((ArrayList<?>) value).isEmpty()) {
            return;
        }
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.setAsync(value, 60 * 60 * 24 * 7, TimeUnit.SECONDS);
    }

    /**
     * 一天过期
     *
     * @param key   键
     * @param value 值
     * @param <T>   对象类型
     */
    public <T> void cacheObjDay(String key, T value) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.setAsync(value, 60 * 60 * 24, TimeUnit.SECONDS);
    }

    public <T> void cacheObj(String key, T value, Integer seconds) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.setAsync(value, seconds, TimeUnit.SECONDS);
    }

    /**
     * 一月过期
     *
     * @param key   键
     * @param value 值
     * @param <T>   对象类型
     */
    public <T> void cacheObjMon(String key, T value) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.setAsync(value, 60 * 60 * 24 * 30, TimeUnit.SECONDS);
    }

    /**
     * 换成对象
     * 不设置过期时间
     *
     * @param key   键
     * @param value 值
     * @param <T>   对象类型
     */
    public <T> void cacheObj(String key, T value) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.setAsync(value);
    }

    /**
     * 从缓存获取对象
     *
     * @param key 键
     * @param <T> 对象类型
     * @return 对象
     */
    public <T> T getObject(String key) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        return bucket.get();
    }

    /**
     * 向列表添加元素
     *
     * @param listName 列表名称
     * @param value    元素值
     * @param <T>      元素类型
     */
    public <T> void addToList(String listName, T value) {
        RList<T> list = redissonClient.getList(listName);
        list.add(value);
    }

    /**
     * 从列表获取元素
     *
     * @param listName 列表名称
     * @param index    索引
     * @param <T>      元素类型
     * @return 元素
     */
    public <T> T getFromList(String listName, int index) {
        RList<T> list = redissonClient.getList(listName);
        return list.get(index);
    }

    /**
     * 获取整个列表
     *
     * @param listName key
     * @param <T>      对象
     * @return list
     */
    public <T> List<T> getEntireList(String listName) {
        RList<T> list = redissonClient.getList(listName);
        return list.readAll();
    }

    /**
     * 向集合添加元素
     *
     * @param setName 集合名称
     * @param value   元素值
     * @param <T>     元素类型
     */
    public <T> void addToSet(String setName, T value) {
        RSet<T> set = redissonClient.getSet(setName);
        set.add(value);
    }

    /**
     * 判断集合是否包含元素
     *
     * @param setName 集合名称
     * @param value   元素值
     * @param <T>     元素类型
     * @return 是否包含
     */
    public <T> boolean isSetContains(String setName, T value) {
        RSet<T> set = redissonClient.getSet(setName);
        return set.contains(value);
    }

    /**
     * 向映射添加键值对
     *
     * @param mapName 映射名称
     * @param key     键
     * @param value   值
     * @param <K>     键类型
     * @param <V>     值类型
     */
    public <K, V> void putToMap(String mapName, K key, V value) {
        RMap<K, V> map = redissonClient.getMap(mapName);
        map.put(key, value);
    }

    /**
     * 从映射获取值
     *
     * @param mapName 映射名称
     * @param key     键
     * @param <K>     键类型
     * @param <V>     值类型
     * @return 值
     */
    public <K, V> V getFromMap(String mapName, K key) {
        RMap<K, V> map = redissonClient.getMap(mapName);
        return map.get(key);
    }

    /**
     * 根据 key 删除缓存
     *
     * @param key 要删除的缓存的 key
     * @return 是否删除成功
     */
    public boolean delCache(String key) {
        return redissonClient.getKeys().delete(key) > 0;
    }

    /**
     * 移除列表中指定元素
     *
     * @param listName 列表名称
     * @param value    要移除的元素
     * @param <T>      元素类型
     * @return 是否移除成功
     */
    public <T> boolean removeFromList(String listName, T value) {
        RList<T> list = redissonClient.getList(listName);
        return list.remove(value);
    }
}